using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;

namespace PSE.Hosting.ServiceHoster.Configuration
{
    /// <summary>
    /// Represents a configuration element containing a collection of Packages
    /// </summary>
    internal class PackagesCollection : ConfigurationElementCollection
    {
        #region Constructor

        /// <summary>
        /// Creates a new instance of the 
        /// <see cref="PSE.Hosting.ServiceHoster.Configuration.AssembliesCollection"/> class.
        /// </summary>
        internal PackagesCollection()
        {
        }

        #endregion

        #region Public Members

        /// <summary>
        /// Specifies the type of the 
        /// <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> objects in the collection.
        /// </summary>
        internal ConfigurationElementCollectionType CollectionType
        {
            get { return ConfigurationElementCollectionType.AddRemoveClearMap; }
        }

        /// <summary>
        /// Gets the configuration element at the specified index location.
        /// </summary>
        /// <param name="index">The index location of the 
        /// <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> specfied to return.</param>
        /// <returns>The configuration element at the specified index location.</returns>
        internal PackageConfigurationElement this[int index]
        {
            get { return (PackageConfigurationElement)BaseGet(index); }
            set
            {
                if (BaseGet(index) != null)
                    BaseRemove(index);
                BaseAdd(index, value);
            }
        }

        /// <summary>
        /// Gets the configuration element by its name.
        /// </summary>
        /// <param name="name">The name of the element to return.</param>
        /// <returns>The specified configuration element.</returns>
        internal new PackageConfigurationElement this[string name]
        {
            get { return (PackageConfigurationElement)BaseGet(name); }
        }

        /// <summary>
        /// Gets the index of the specified 
        /// <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/>.
        /// </summary>
        /// <param name="assembly">The <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> for the specified index location.</param>
        /// <returns>The index of the specified <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/>.</returns>
        internal int IndexOf(PackageConfigurationElement package)
        {
            return BaseIndexOf(package);
        }

        /// <summary>
        /// Adds a configuration element to the configuration element collection.
        /// </summary>
        /// <param name="assembly">The <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> to add.</param>
        internal void Add(PackageConfigurationElement package)
        {
            BaseAdd(package);
        }

        /// <summary>
        /// Removes the <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> specified from the collection.
        /// </summary>
        /// <param name="assembly">The <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> to remove.</param>
        internal void Remove(PackageConfigurationElement package)
        {
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }

            if (BaseIndexOf(package) >= 0)
                BaseRemove(package.Name);
        }

        /// <summary>
        /// Removes the 
        /// <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> at the specified index location.
        /// </summary>
        /// <param name="index">The index location of the 
        /// <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> to remove.</param>
        internal void RemoveAt(int index)
        {
            BaseRemoveAt(index);
        }

        /// <summary>
        /// Removes a <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> from the collection.
        /// </summary>
        /// <param name="name">The key of the <see cref="PSE.Hosting.ServiceHoster.Configuration.AssemblyConfigurationElement"/> to remove.</param>
        internal void Remove(string name)
        {
            BaseRemove(name);
        }

        /// <summary>
        /// Removes all configuration element objects from the collection.
        /// </summary>
        internal void Clear()
        {
            BaseClear();
        }

        #endregion

        #region Protected Members

        /// <summary>
        /// Creates a new configuration element.
        /// </summary>
        /// <returns>The element created.</returns>
        protected override ConfigurationElement CreateNewElement()
        {
            return new PackageConfigurationElement();
        }

        /// <summary>
        /// Creates a new configuration element.
        /// </summary>
        /// <param name="elementName">The name of the <see cref="System.Configuration.ConfigurationElement"/> to be created.</param>
        /// <returns>The new <see cref="System.Configuration.ConfigurationElement"/>.</returns>
        protected override ConfigurationElement CreateNewElement(string elementName)
        {
            return new PackageConfigurationElement(elementName, string.Empty, string.Empty, string.Empty);
        }

        /// <summary>
        /// Gets the name of a specified configuration element.
        /// </summary>
        /// <param name="element">The <see cref="System.Configuration.ConfigurationElement"/>.</param>
        /// <returns>The name of the specified configuration element.</returns>
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((PackageConfigurationElement)element).Name;
        }

        #endregion
    }
}
